package com.tfdy;

import com.tfdy.dao.SqliteDao;
import com.tfdy.util.Constants;
import com.tfdy.util.shp.CovertShpCoords;
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;

import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class Main extends Application {

    private Button okBtn;
    private Button annoBtn;
    private Button dianBtn;
    private Button xianBtn;
    private TextField pointBufferText;
    private TextField lineBufferText;
    private TextField annoPathText;
    private TextField dianPathText;
    private TextField xianPathText;
    private Button destBtn;
    private TextField destPathText;
    private ComboBox sourceType;
    private ProgressBar progressBar;


    Service<Integer> service = new Service<Integer>() {

        @Override
        protected Task<Integer> createTask() {
            return new Task<Integer>() {

                @Override
                protected Integer call() throws Exception {
                    String fileType = sourceType.getValue().toString();
                    String pointBuffer = pointBufferText.getText();
                    String lineBuffer = lineBufferText.getText();
                    String annoFilePath = annoPathText.getText();
                    String dianFilePath = dianPathText.getText();
                    String xianFilePath = xianPathText.getText();
                    List<Point> pointList = new ArrayList<>();
                    List<Map<Integer,String>> listDian = new ArrayList<>();
                    List<Map<Integer,String>> listXian = new ArrayList<>();
                    if(StringUtils.isNotBlank(dianFilePath)){
                        listDian = CovertShpCoords.readShpPoint(pointBuffer,fileType,pointList,dianFilePath, annoFilePath);
                        //return null;
                    }
                    if(StringUtils.isNotBlank(xianFilePath)){
                        listXian = CovertShpCoords.readShpLine(lineBuffer,fileType,pointList,xianFilePath, annoFilePath);
                        //return null;
                    }
                    String destFilePath = destPathText.getText();
                    //SqliteDao  sqliteDao = new SqliteDao();
                    updateMessage("开始获取点数据");
                    //List<Map<Integer,String>> listDian = sqliteDao.getDianListMapByType(fileType,sourceFilePath);
                    updateMessage("开始获取线数据");
                    //List<Map<Integer,String>> listXian = sqliteDao.getDianListMapByType(fileType,sourceFilePath);
                    int count = listDian.size() + listXian.size() + 4;
                    int processInt = 1;
                    updateProgress(processInt, count);
                    processInt++;
                    File file = new File(destFilePath);// 创建excel文件对象
                    FileOutputStream fOut = null;
                    try {
                        updateMessage("开始创建Excel文件");
                        // 创建一个新的HSSFWorkbook对象
                        HSSFWorkbook workbook = new HSSFWorkbook();
                        // 创建单元格的格式，如居中、左对齐等
                        HSSFCellStyle cellStyle = workbook.createCellStyle();
                        cellStyle.setAlignment(HorizontalAlignment.CENTER); // 水平方向上居中对齐
                        // 垂直方向上居中对齐
                        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                        // 下面将建立一个4行3列的表。第一行为表头。
                        int rowNum = 0;// 行标
                        int colNum = 0;// 列标
                        // 建立表头信息
                        // 创建一个Excel的工作表，可以指定工作表的名字
                        HSSFSheet sheet = workbook.createSheet( "点表");
                        HSSFRow row = sheet.createRow((short) rowNum); // 在索引0的位置创建行
                        HSSFCell cell = null; // 单元格
                        Map<Integer, String> dianMap = Constants.getDianMap();
                        updateMessage("开始输出点表头数据");
                        for (colNum = 0; colNum < dianMap.size(); colNum++) {
                            // 在当前行的colNum列上创建单元格
                            cell = row.createCell((short) colNum);
                            // 定义单元格为字符类型，也可以指定为日期类型、数字类型
                            cell.setCellType(CellType.STRING);
                            // 定义编码方式，为了支持中文，这里使用了ENCODING_UTF_16
                            cell.setCellStyle(cellStyle); // 为单元格设置格式
                            cell.setCellValue(dianMap.get(colNum)); // 添加内容至单元格
                        }
                        updateProgress(processInt, count);
                        processInt++;
                        updateMessage("开始输出点数据");
                        rowNum++;
                        for (; rowNum < listDian.size() + 1; rowNum++) {
                            // 新建第rowNum行
                            Map<Integer,String> mapObj = listDian.get(rowNum - 1);
                            row = sheet.createRow((short) rowNum);
                            for (colNum = 0; colNum < dianMap.size() ; colNum++) {
                                // 在当前行的colNum位置创建单元格
                                cell = row.createCell((short) colNum);
                                //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                                cell.setCellStyle(cellStyle);
                                cell.setCellValue(mapObj.get(colNum));
                            }
                            updateProgress(processInt, count);
                            processInt ++;
                        }
                        updateMessage("开始输出线表头数据");
                        sheet = workbook.createSheet( "线表");
                        rowNum = 0;// 行标
                        colNum = 0;// 列标
                        // 建立表头信息
                        row = sheet.createRow((short) rowNum); // 在索引0的位置创建行
                        cell = null; // 单元格
                        Map<Integer, String> xianMap = Constants.getXianMap(fileType);
                        for (colNum = 0; colNum < xianMap.size(); colNum++) {
                            // 在当前行的colNum列上创建单元格
                            cell = row.createCell((short) colNum);
                            // 定义单元格为字符类型，也可以指定为日期类型、数字类型
                            cell.setCellType(CellType.STRING);
                            // 定义编码方式，为了支持中文，这里使用了ENCODING_UTF_16
                            cell.setCellStyle(cellStyle); // 为单元格设置格式
                            cell.setCellValue(xianMap.get(colNum)); // 添加内容至单元格
                        }
                        updateProgress(processInt, count);
                        processInt ++;
                        updateMessage("开始输出线数据");
                        rowNum ++;
                        for (; rowNum < listXian.size() + 1; rowNum++) {
                            // 新建第rowNum行
                            Map<Integer,String> mapObj = listXian.get(rowNum - 1);
                            row = sheet.createRow((short) rowNum);
                            for (colNum = 0; colNum < xianMap.size(); colNum++) {
                                // 在当前行的colNum位置创建单元格
                                cell = row.createCell((short) colNum);
                                //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                                cell.setCellStyle(cellStyle);
                                cell.setCellValue(mapObj.get(colNum));
                            }
                            updateProgress(processInt, count);
                            processInt++;
                        }
                        updateMessage("开始输出文件");
                        // 新建一输出文件流
                        fOut = new FileOutputStream(file);
                        // 将创建的内容写到指定的Excel文件中
                        workbook.write(fOut);
                        fOut.flush();
                        fOut.close();// 操作结束，关闭文件
                        updateProgress(processInt, count);
                        System.out.println("Excel文件创建成功！\nExcel文件的存放路径为：" + file.getAbsolutePath());

                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("Excel文件" + file.getAbsolutePath() + "创建失败\n其原因为：" + e);
                    } finally {
                        if (fOut != null) {
                            try {
                                fOut.close();
                            } catch (IOException e1) {

                            }
                        }
                        updateMessage("导出结束！");
                        Alert alert = new Alert(Alert.AlertType.INFORMATION);
                        alert.titleProperty().set("信息");
                        alert.headerTextProperty().set("导出成功！");
                        alert.showAndWait();
                    }
                    return null;
                };
            };
        }

    };

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("sample.fxml"));
        initView(root, primaryStage);
        primaryStage.getIcons().add(new Image("logo.png"));
        primaryStage.setTitle("图知盛景");
        primaryStage.setScene(new Scene(root, 560, 365));
        primaryStage.show();
    }

    private int readFile(String path){
        int num = 0;
        try {
            int position=0;
            String[] bufstring=new String[1024];
            //打开带读取的文件
            BufferedReader br = new BufferedReader(new FileReader(path));
            String line = null;
            line=br.readLine();
            num = Integer.valueOf(line);
            br.close();//关闭
        }catch (IOException ex){

        }
        return num;
    }
    private void writeFile(String path, int num){
        try{
            num++;
            OutputStream os = new FileOutputStream(path);
            PrintWriter pw=new PrintWriter(os);
            pw.print(num);
            pw.close();
            os.close();
        }catch(IOException ex){

        }
    }
    private void initView(Parent parent, Stage primaryStage) {
        this.okBtn = (Button) parent.lookup("#okBtn");
        this.pointBufferText = (TextField) parent.lookup("#pointBufferText");
        this.pointBufferText.setText("0.3");
        this.lineBufferText = (TextField) parent.lookup("#lineBufferText");
        this.lineBufferText.setText("1.0");
        this.annoBtn = (Button) parent.lookup("#annoBtn");
        this.annoPathText = (TextField) parent.lookup("#annoPathText");
        //this.annoPathText.setText("G:\\cad\\shp\\2F_Annotation.shp");
        this.dianBtn = (Button) parent.lookup("#dianBtn");
        this.dianPathText = (TextField) parent.lookup("#dianPathText");
        //this.dianPathText.setText("G:\\cad\\shp\\2F_POINT.shp");
        this.xianBtn = (Button) parent.lookup("#xianBtn");
        this.xianPathText = (TextField) parent.lookup("#xianPathText");
        //this.xianPathText.setText("G:\\cad\\shp\\2F_LINE.shp");
        this.sourceType = (ComboBox) parent.lookup("#sourceType");
        this.sourceType.getItems().addAll("雨水", "污水");
        this.sourceType.setValue("雨水");
        this.sourceType.setOnHidden((e) -> {
            if(StringUtils.isNotBlank(this.destPathText.getText())){
                int lastIndex = this.destPathText.getText().lastIndexOf("\\");
                String destPath = this.destPathText.getText().substring(0, lastIndex + 1);
                this.destPathText.setText(destPath + this.sourceType.getValue() + ".xls");
            }
        });
        this.okBtn.setOnMouseClicked((e) -> {
            if (StringUtils.isBlank(sourceType.getValue().toString())) {
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.titleProperty().set("信息");
                alert.headerTextProperty().set("请先选择一个文件类型！");
                alert.showAndWait();
                return;
            }
            if(annoPathText.getText().indexOf(".shp") > 0 && dianPathText.getText().indexOf(".shp") > 0 && xianPathText.getText().indexOf(".shp") > 0){
                String testpath = getClass().getClassLoader().getResource("test").toString();
                String relpath = testpath.replace("file:/","");
                int num = readFile(relpath);
                writeFile(relpath, num);
                SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
                int nowdate = Integer.valueOf(sdf.format(new Date()));

                if(num < 200 || nowdate < 20200430){
                    progressBar.progressProperty().bind(service.progressProperty());
                    service.restart();
                }

            }else{
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.titleProperty().set("信息");
                alert.headerTextProperty().set("请先选择shp类型的文件！");
                alert.showAndWait();
            }
        });

        this.annoBtn.setOnMouseClicked((e) -> {
            FileChooser fileChooser = new FileChooser();
            String annoPathString = this.annoPathText.getText();
            if(StringUtils.isNotBlank(annoPathString)){
                int lastIndex = annoPathString.lastIndexOf("\\");
                String annoPath = annoPathString.substring(0, lastIndex + 1);
                String annoFileName = annoPathString.substring(lastIndex + 1,annoPathString.length());
                fileChooser.setInitialDirectory(new File(annoPath));
                fileChooser.setInitialFileName(annoFileName);
            }

            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("文件", "*.shp")
            );
            File file = fileChooser.showOpenDialog(primaryStage);
            if(null != file){
                String path = file.getPath();
                annoPathText.setText(path);
                if (StringUtils.isBlank(annoPathText.getText())) {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.titleProperty().set("信息");
                    alert.headerTextProperty().set("请先选择一个标注图层！");
                    alert.showAndWait();
                    return;
                }
            }
        });

        this.dianBtn.setOnMouseClicked((e) -> {
            FileChooser fileChooser = new FileChooser();
            String dianPathString = this.dianPathText.getText();
            if(StringUtils.isNotBlank(dianPathString)){
                int lastIndex = dianPathString.lastIndexOf("\\");
                String dianPath = dianPathString.substring(0, lastIndex + 1);
                String dianFileName = dianPathString.substring(lastIndex + 1, dianPathString.length());
                fileChooser.setInitialDirectory(new File(dianPath));
                fileChooser.setInitialFileName(dianFileName);
            }

            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("文件", "*.shp")
            );
            File file = fileChooser.showOpenDialog(primaryStage);
            if(null != file){
                String path = file.getPath();
                dianPathText.setText(path);
                if (StringUtils.isBlank(dianPathText.getText())) {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.titleProperty().set("信息");
                    alert.headerTextProperty().set("请先选择一个点图层！");
                    alert.showAndWait();
                    return;
                }
            }
        });
        this.xianBtn.setOnMouseClicked((e) -> {
            FileChooser fileChooser = new FileChooser();
            String xianPathString = this.xianPathText.getText();
            if(StringUtils.isNotBlank(xianPathString)){
                int lastIndex = xianPathString.lastIndexOf("\\");
                String xianPath = xianPathString.substring(0, lastIndex + 1);
                String xianFileName = xianPathString.substring(lastIndex + 1, xianPathString.length());
                fileChooser.setInitialDirectory(new File(xianPath));
                fileChooser.setInitialFileName(xianFileName);
            }
            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("文件", "*.shp")
            );
            File file = fileChooser.showOpenDialog(primaryStage);
            if(null!=file){
                String path = file.getPath();
                xianPathText.setText(path);
                if (StringUtils.isBlank(xianPathText.getText())) {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.titleProperty().set("信息");
                    alert.headerTextProperty().set("请先选择一个线图层！");
                    alert.showAndWait();
                    return;
                }
            }
        });
        this.destBtn = (Button) parent.lookup("#destBtn");
        this.destPathText = (TextField) parent.lookup("#destPathText");
        //this.destPathText.setText("D:\\cad\\shp\\" + this.sourceType.getValue() + ".xls");
        this.progressBar = (ProgressBar)parent.lookup("#progressBar");
        this.destBtn.setOnMouseClicked((e) -> {
            FileChooser fileChooser = new FileChooser();
            String destPathString = this.destPathText.getText();
            if(StringUtils.isNotBlank(destPathString)){
                int lastIndex = destPathString.lastIndexOf("\\");
                String destPath = destPathString.substring(0, lastIndex + 1);
                String destFileName = destPathString.substring(lastIndex + 1, destPathString.length());
                fileChooser.setInitialDirectory(new File(destPath));
                fileChooser.setInitialFileName(destFileName);
            }
            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("EXCEL", "*.xls")
            );
            File file = fileChooser.showSaveDialog(primaryStage);
            if(null != file){
                String path = file.getPath();
                destPathText.setText(path);
            }
        });

    }

    public void readShpToExcel(String fileType, String sourceFilePath, String destFilePath) {
        //CovertShpCoords.readShpPoint(sourceFilePath);
    }

    public void exportToExcel(String fileType, String sourceFilePath, String destFilePath) {
        File file = new File(destFilePath);// 创建excel文件对象
        FileOutputStream fOut = null;
        try {
            // 创建一个新的HSSFWorkbook对象
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 创建单元格的格式，如居中、左对齐等
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.CENTER); // 水平方向上居中对齐
            // 垂直方向上居中对齐
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            // 下面将建立一个4行3列的表。第一行为表头。
            int rowNum = 0;// 行标
            int colNum = 0;// 列标
            // 建立表头信息
            // 创建一个Excel的工作表，可以指定工作表的名字
            HSSFSheet sheet = workbook.createSheet(fileType + "点表");
            HSSFRow row = sheet.createRow((short) rowNum); // 在索引0的位置创建行
            HSSFCell cell = null; // 单元格
            Map<Integer, String> dianMap = Constants.getDianMap();
            for (colNum = 0; colNum < dianMap.size(); colNum++) {
                // 在当前行的colNum列上创建单元格
                cell = row.createCell((short) colNum);
                // 定义单元格为字符类型，也可以指定为日期类型、数字类型
                cell.setCellType(CellType.STRING);
                // 定义编码方式，为了支持中文，这里使用了ENCODING_UTF_16
                cell.setCellStyle(cellStyle); // 为单元格设置格式
                cell.setCellValue(dianMap.get(colNum)); // 添加内容至单元格
            }
            SqliteDao  sqliteDao = new SqliteDao();
            List<Map<Integer,String>> listDian = sqliteDao.getDianListMapByType(fileType,sourceFilePath);
            rowNum++;
            for (; rowNum < listDian.size() + 1; rowNum++) {
                // 新建第rowNum行
                Map<Integer,String> mapObj = listDian.get(rowNum - 1);
                row = sheet.createRow((short) rowNum);
                for (colNum = 0; colNum < dianMap.size() ; colNum++) {
                    // 在当前行的colNum位置创建单元格
                    cell = row.createCell((short) colNum);
                    //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                    cell.setCellStyle(cellStyle);
                    cell.setCellValue(mapObj.get(colNum));
                }
            }

            sheet = workbook.createSheet(fileType+"线表");
            rowNum = 0;// 行标
            colNum = 0;// 列标
            // 建立表头信息
            row = sheet.createRow((short) rowNum); // 在索引0的位置创建行
            cell = null; // 单元格
            Map<Integer, String> xianMap = Constants.getXianMap(fileType);
            for (colNum = 0; colNum < xianMap.size(); colNum++) {
                // 在当前行的colNum列上创建单元格
                cell = row.createCell((short) colNum);
                // 定义单元格为字符类型，也可以指定为日期类型、数字类型
                cell.setCellType(CellType.STRING);
                // 定义编码方式，为了支持中文，这里使用了ENCODING_UTF_16
                cell.setCellStyle(cellStyle); // 为单元格设置格式
                cell.setCellValue(xianMap.get(colNum)); // 添加内容至单元格
            }
            List<Map<Integer,String>> listXian = sqliteDao.getDianListMapByType(fileType,sourceFilePath);
            rowNum++;
            for (; rowNum < listXian.size() + 1; rowNum++) {
                // 新建第rowNum行
                Map<Integer,String> mapObj = listXian.get(rowNum - 1);
                row = sheet.createRow((short) rowNum);
                for (colNum = 0; colNum < xianMap.size(); colNum++) {
                    // 在当前行的colNum位置创建单元格
                    cell = row.createCell((short) colNum);
                    //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                    cell.setCellStyle(cellStyle);
                    cell.setCellValue(mapObj.get(colNum));
                }
            }
            // 新建一输出文件流
            fOut = new FileOutputStream(file);
            // 将创建的内容写到指定的Excel文件中
            workbook.write(fOut);
            fOut.flush();
            fOut.close();// 操作结束，关闭文件
            System.out.println("Excel文件创建成功！\nExcel文件的存放路径为：" + file.getAbsolutePath());

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Excel文件" + file.getAbsolutePath() + "创建失败\n其原因为：" + e);
        } finally {
            if (fOut != null) {
                try {
                    fOut.close();
                } catch (IOException e1) {
                }
            }
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
